﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Configuration;

using Norm;
using Norm.Attributes;
using Norm.Collections;
using Norm.Configuration;
using Norm.Linq;
using Norm.Responses;

namespace EazyProviders.MongoDb
{

    /*internal*/ public class MongoSession : IDisposable
    {

        private readonly IMongo _provider;
        private string connstring = string.Empty;

        public MongoSession()
        {
            connstring = ConfigurationManager.AppSettings.Get("mongodb.membership.connstring");
            _provider = Mongo.Create(connstring);
        }

        public MongoSession(string connectionString)
        {
            connstring = connectionString;
            _provider = Mongo.Create(connstring);
        }

        public IMongoDatabase MongoDatabase { get { return this._provider.Database; } }


        public IQueryable<MembershipApplication> Applications
        {
            get { return _provider.GetCollection<MembershipApplication>().AsQueryable(); }
        }


        public IQueryable<MembershipAccount> Users
        {
            get { return _provider.GetCollection<MembershipAccount>().AsQueryable(); }
        }
        
        public IQueryable<MembershipRole> Roles
        {
            get { return _provider.GetCollection<MembershipRole>().AsQueryable(); }
        }

        //public IQueryable<UsersInRolesEntity> UsersInRoles
        //{
        //    get { return _provider.GetCollection<UsersInRolesEntity>().AsQueryable(); }
        //}
      


        #region IDisposable Members

        public void Dispose()
        {
            _provider.Dispose();
        }

        #endregion

        public T MapReduce<T>(string map, string reduce)
        {
            T result = default(T);
            MapReduce mr = _provider.Database.CreateMapReduce();

            MapReduceResponse response =
                mr.Execute(new MapReduceOptions(typeof(T).Name)
                {
                    Map = map,
                    Reduce = reduce
                });

            IMongoCollection<MapReduceResult<T>> coll = response.GetCollection<MapReduceResult<T>>();
            MapReduceResult<T> r = coll.Find().FirstOrDefault();
            result = r.Value;

            return result;
        }

        public void Add<T>(T item) where T : class, new()
        {
            _provider.Database.GetCollection<T>().Insert(item);
        }

        public void Add<T>(IEnumerable<T> items) where T : class, new()
        {
            _provider.Database.GetCollection<T>().Insert(items);
        }

        public void Save<T>(T item) where T : class, new()
        {
            _provider.Database.GetCollection<T>().Save(item);
        }

        public void Update<T>(T item) where T : class, new()
        {
            Save(item);
        }

        public void Delete<T>(T item) where T : class, new()
        {
            _provider.Database.GetCollection<T>().Delete(item);
            
        }

        public void Drop<T>()
        {

            var col=_provider.Database.GetCollection<T>();
            _provider.Database.DropCollection(typeof(T).Name);
        }

        public void CreateCappedCollection(string name)
        {
            _provider.Database.CreateCollection(new CreateCollectionOptions(name));
        }

    }

}
